package cn.yuhh.api.service;


import cn.yuhh.api.annotation.OpenService;
import cn.yuhh.api.controller.HttpController;
import cn.yuhh.api.exception.ApiException;
import cn.yuhh.api.validator.Validator;
import cn.yuhh.core.domain.DeclareInfo;
import cn.yuhh.core.domain.DeclareLog;
import cn.yuhh.core.type.ResponseHeader;
import cn.yuhh.core.type.Whether;
import cn.yuhh.core.util.ConvertUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.magic.spring.mongo.Mongo;
import org.apache.commons.beanutils.BeanUtils;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;


/**
 * @author ysw
 * @create 2019-02-24 21:55
 * @description
 **/
public abstract class AbstractApiService  implements IApiService {

    protected static Map<String, String> sessionManager = new HashMap();


    protected Logger log = LoggerFactory.getLogger(getClass());


    @Override
    public void validate(Map request) {
//        sessionValidate(request);
        // 时间戳验证
        // timestampValidate(request);
        // 请求参数验证
        paramValidate(request);
    }


    private boolean isOpenService(Class clazz) {
        return clazz.isAnnotationPresent(OpenService.class) || clazz.getSuperclass() != Object.class && isOpenService(clazz.getSuperclass());
    }


    public void sessionValidate(Map request) {
        //session验证
        if (!isOpenService(this.getClass())) {
            sessionVerify(selfId(request), string(request,"sessionId"));
        }
    }

    private void sessionVerify(String selfId, String token) {
        if (selfId == null || StringUtils.isEmpty(token)) {
            throw new ApiException(ResponseHeader.NOT_AUTHORIZED);
        }
    }



    private void timestampValidate(Map request) {
        long timestamp = (long) request.get("timestamp");
        if (Math.abs(System.currentTimeMillis() / 1000 - timestamp) > 120) {
            throw new ApiException();
        }
    }

    protected  void paramValidate(Map request) {
        try {
            Validator.validate(this.getClass(), request);
        } catch (IllegalAccessException e) {
            log.error("验证异常",e);
        } catch (InstantiationException e) {
            log.error("验证异常",e);
        }
    };

    public static  <T> T map2bean(Class<T> clazz,Map map){
        return  JSON.parseObject(JSON.toJSONString(map),clazz);
    }

    protected Mongo mongoId(Map request){
        return Mongo.buildMongo().eq("_id", new ObjectId(id(request)));
    }

    protected Whether whether(Map request){
        return Whether.valueOf( ConvertUtil.String(request.get("pass"),"Y"));
    }

    protected String selfId(Map request){
        return string(request, "selfId");
    }

    public int limit(Map request) {
        return ConvertUtil.Int(ConvertUtil.Int(request.get("limit"), 20));
    }

    public int page(Map request) {
        return ConvertUtil.Int(ConvertUtil.Int(request.get("page"), 1));
    }

    public Long userId(Map request) {
        return ConvertUtil.formatLong(request.get("selfId"));
    }


    public String id(Map request) {
        return ConvertUtil.String(request.get("id"));
    }

    public String areaInfo(Map request) {
        JSONObject jsonObject = (JSONObject) request.get("areaInfo");
        return ConvertUtil.String(jsonObject.get("countyCode"));
    }

    public String countyCode(Map request) {
        return ConvertUtil.String(request.get("countyCode"));
    }

    public String sessionId(Map request) {
        return ConvertUtil.String(request.get("sessionId"));
    }


    public Long formatLong(Object o) {
        return ConvertUtil.formatLong(o);
    }

    public Integer formatInt(Object o) {
        return ConvertUtil.IntNull(o);
    }

    public BigDecimal formatBigDecimal(Map request, String key){
        return ConvertUtil.formatBigDecimimal(request.get(key));
    }

    public String string(Map request, String key) {
        return ConvertUtil.String(request.get(key));
    }


    public Integer integer(Map request, String key) {
        return ConvertUtil.Integer(request.get(key));
    }

    public void declareLog(String declareInfoId){
        DeclareInfo declareInfo = Mongo.buildMongo().eq("_id", new ObjectId(declareInfoId)).findOne(DeclareInfo.class);
        declareLog(declareInfo);
    }
    public void declareLog(DeclareInfo declareInfo) {
       new Thread(new Runnable() {
           @Override
           public void run() {
               DeclareLog declareLog = new DeclareLog();
               org.springframework.beans.BeanUtils.copyProperties(declareInfo, declareLog);
               declareLog.setId(null);
               declareLog.setRelId(declareInfo.getId());
               Mongo.buildMongo().insert(declareLog);
           }
       }).start();
    }

}

